package com.flyme.module.base.provider.service.impl;

import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.flyme.common.core.exception.OpenMessageException;
import com.flyme.common.core.model.query.CriteriaQuery;
import com.flyme.common.core.utils.ApiAssert;
import com.flyme.common.core.utils.StringUtils;
import com.flyme.core.base.supper.service.impl.BaseServiceImpl;
import com.flyme.module.base.client.constants.BaseConstants;
import com.flyme.module.base.client.entity.SystemRole;
import com.flyme.module.base.client.entity.SystemUserRole;
import com.flyme.module.base.provider.mapper.SysRoleMapper;
import com.flyme.module.base.provider.service.SysAuthorizeService;
import com.flyme.module.base.provider.service.SysRoleService;
import com.flyme.module.base.provider.service.SysUserRoleService;
import org.assertj.core.util.Lists;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.Date;
import java.util.List;


/**
 * @author zyf
 */
@Service
@Transactional(rollbackFor = Exception.class)
public class SysRoleServiceImpl extends BaseServiceImpl<SysRoleMapper, SystemRole> implements SysRoleService {

    @Autowired
    private SysUserRoleService userRoleService;
    @Autowired
    private SysAuthorizeService authorizeService;


    /**
     * 添加角色
     *
     * @param role 角色
     * @return
     */
    @Override
    public Boolean addRole(SystemRole role) {
        if (isExist(role.getRoleCode())) {
            throw new OpenMessageException(String.format("%s角色编码已存在,不允许重复添加", role.getRoleCode()));
        }
        if (role.getStatus() == null) {
            role.setStatus(BaseConstants.ENABLED);
        }
        if (role.getIsPersist() == null) {
            role.setIsPersist(BaseConstants.DISABLED);
        }
        role.setCreateTime(new Date());
        role.setUpdateTime(role.getCreateTime());
        return save(role);
    }

    /**
     * 更新角色
     *
     * @param role 角色
     * @return
     */
    @Override
    public Boolean updateRole(SystemRole role) {
        ApiAssert.notNull("ID不能为空", role.getId());
        SystemRole savedRole = getById(role.getId());
        if (role == null) {
            throw new OpenMessageException(String.format("roleId=%s不存在", role.getId()));
        }
        if (!savedRole.getRoleCode().equals(role.getRoleCode())) {
            // 和原来不一致重新检查唯一性
            if (isExist(role.getRoleCode())) {
                throw new OpenMessageException(String.format("%s菜单编码已存在,不允许重复添加", role.getRoleCode()));
            }
        }
        role.setUpdateTime(new Date());
        return saveOrUpdate(role);
    }

    /**
     * 删除角色
     *
     * @param roleId 角色ID
     * @return
     */
    @Override
    public Boolean removeRole(Long roleId) {
        SystemRole role = getById(roleId);
        if (role != null && role.getIsPersist().equals(BaseConstants.ENABLED)) {
            throw new OpenMessageException(String.format("保留数据,不允许删除"));
        }
        if (roleId == null) {
            return false;
        }
        int count = getCountByRole(roleId.toString());
        if (count > 0) {
            throw new OpenMessageException("该角色下存在授权组员,不允许删除!");
        }
        return removeById(roleId);
    }

    /**
     * 检测角色编码是否存在
     *
     * @param roleCode
     * @return
     */
    @Override
    public Boolean isExist(String roleCode) {
        if (StringUtils.isBlank(roleCode)) {
            throw new OpenMessageException("roleCode is null");
        }
        int n = count(q().eq("roleCode", roleCode));
        return n > 0;
    }

    /**
     * 成员分配角色
     *
     * @param userId
     * @param roles
     * @return
     */
    @Override
    public Boolean saveUserRoles(Long userId, Long... roles) {
        if (userId == null || roles == null) {
            return false;
        }
        if (roles.length == 0) {
            return false;
        }
        // 先清空,在添加
        removeMemberRoles(userId);
        List<SystemUserRole> list = Lists.newArrayList();
        for (Long roleId : roles) {
            SystemUserRole roleUser = new SystemUserRole();
            roleUser.setUserId(userId);
            roleUser.setRoleId(roleId);
            list.add(roleUser);
        }
        // 批量保存
        return userRoleService.saveBatch(list);
    }

    /**
     * 成员分配角色
     *
     * @param userId
     * @param roles
     * @return
     */
    @Override
    public Boolean saveUserRoles(Long userId, String... roleCodes) {
        if (userId == null || roleCodes == null) {
            return false;
        }
        if (roleCodes.length == 0) {
            return false;
        }
        // 先清空,在添加
        removeMemberRoles(userId);
        List<SystemUserRole> list = Lists.newArrayList();
        for (String roleCode : roleCodes) {
            SystemRole role = getOne(q().eq("roleCode", roleCode));
            SystemUserRole roleUser = new SystemUserRole();
            roleUser.setUserId(userId);
            roleUser.setRoleId(role.getId());
            list.add(roleUser);
        }
        // 批量保存
        return userRoleService.saveBatch(list);
    }

    /**
     * 获取角色所有授权组员数量
     *
     * @param roleId
     * @return
     */
    @Override
    public int getCountByRole(String roleId) {
        CriteriaQuery cq = new CriteriaQuery<SystemUserRole>();
        int result = userRoleService.count(cq.eq("roleId", roleId));
        return result;
    }

    /**
     * 获取组员角色数量
     *
     * @param userId
     * @return
     */
    @Override
    public int getCountByUser(Long userId) {
        CriteriaQuery cq = new CriteriaQuery<SystemUserRole>();
        int result = userRoleService.count(cq.eq("userId", userId));
        return result;
    }

    /**
     * 移除角色所有组员
     *
     * @param roleId
     * @return
     */
    @Override
    public Boolean removeRoleUsers(Long roleId) {
        CriteriaQuery cq = new CriteriaQuery<SystemUserRole>();
        return userRoleService.remove(cq.eq("roleId", roleId));
    }

    /**
     * 移除组员的所有角色
     *
     * @param userId
     * @return
     */
    @Override
    public Boolean removeMemberRoles(Long userId) {
        CriteriaQuery cq = new CriteriaQuery<SystemUserRole>();
        return userRoleService.remove(cq.eq("userId", userId));
    }

    @Override
    public Boolean deleteByUserIds(Long[] userIds) {
        ApiAssert.notNull("参数不能为空", userIds);
        UpdateWrapper<SystemUserRole> up = new UpdateWrapper();
        return userRoleService.remove(up.in("userId", userIds));
    }

    /**
     * 批量删除角色
     *
     * @param roleIds
     * @return
     */
    @Override
    public Boolean delByRoleIds(String[] roleIds) {
        ApiAssert.notNull("参数不能为空", roleIds);
        for (String roleId : roleIds) {
            int count = getCountByRole(roleId);
            ApiAssert.lezero("该角色下存在授权用戶,不允许删除!", count);
        }
        //刪除角色授权
        authorizeService.removeGrantAccess(BaseConstants.AUTHORITY_PREFIX_ROLE, roleIds);
        return this.remove(q().in("id", roleIds));
    }

    /**
     * 更新启用禁用
     *
     * @param roleId
     * @param status
     * @return
     */
    @Override
    public Boolean updateStatus(Long roleId, Integer status) {
        SystemRole role = new SystemRole();
        role.setId(roleId);
        role.setStatus(status);
        return saveOrUpdate(role);
    }

    /**
     * 更新启用禁用
     *
     * @param id
     * @param isDefault
     * @return
     */
    @Override
    public Boolean setDefault(Long id, Integer defaultRole) {
        SystemRole role = new SystemRole();
        role.setId(id);
        role.setDefaultRole(defaultRole);
        return saveOrUpdate(role);
    }

    /**
     * 检测是否存在
     *
     * @param userId
     * @param roleId
     * @return
     */
    @Override
    public Boolean isExist(Long userId, Long roleId) {
        CriteriaQuery cq = new CriteriaQuery<SystemUserRole>();
        return userRoleService.count(cq.eq("userId", userId).eq("roleId", roleId)) > 0;
    }


    /**
     * 获取用户角色列表
     *
     * @param userId
     * @return
     */
    @Override
    public List<SystemRole> getUserRoles(Long userId) {
        return list(q().inSql("id", "SELECT roleId from sys_user_role ur  where  sys_role.id=roleId and ur.userId=" + userId));
    }

    /**
     * 获取角色列表
     *
     * @return
     */
    @Override
    public List<SystemRole> selertRoleList() {
        return list(q().eq("status", BaseConstants.ENABLED));
    }

    @Override
    public List<Long> selectRoleIdsByUserId(Long userId) {
        return listObjs(q().select("id").inSql("id", "select roleId from sys_user_role where userId='" + userId + "'"), e -> Long.parseLong(e.toString()));
    }

    /**
     * 根据roleCode查询权限
     */
    public SystemRole findByRoleCode(String roleCode) {
        return getOne(q().eq("roleCode", roleCode));
    }

}
